<?php
/* ************************************************** *\
 * @company		: NovaITech							  *	
 * @author		: van.vo@novaitech.com				  * 
 * @copyright	: 2012								  * 
 * ================================================== *
 * @date		: 03/21/2012
 * @project		: CodeGenerater
 * @description	:
 *		- 
 *
\* ************************************************** */

class xml_model extends CI_Model{
    function __construct( ){
        parent::__construct( );
        $this->load->helper('xml');
        $this->load->helper('array');
    }
    
    
    function duplicate_xml( $table_name ){
        $doc = new DOMDocument( '1.0', 'iso-8859-1');
        $doc->formatOutput = true;
        $doc->preserveWhiteSpace = false;
        $doc->load( PATH_XML . $table_name . "_snippet.xml");
        // New name = CCYYMMDD HH:SS
        $new_name = $table_name . "_".  round(date('Y') / 100, 0) . date('omdHi');
        $doc->save(PATH_XML . $new_name . "_snippet.xml");
        return $new_name;
    }


    
    /* ------------------------------------------------------------ *\
    | - FUNC Purpose	: Change order field in add new item 
    | - Parameters		: 
    |		Name			Type		Description
    |		---------------------------------------------------
    |		$move_from      int         start position							
    |	    $move_to        int         end position
    |       $offset         int         
    | - Return
    |			- N/A
    \* ------------------------------------------------------------ */
    function change_order( $table_name, $move_from, $move_to, $offset = 0){
        $doc = new DOMDocument( '1.0', 'iso-8859-1' );
        $doc->formatOutput = true;
        $doc->preserveWhiteSpace = false;
        $doc->load( PATH_XML . $table_name . "_snippet.xml");
        
        $xpath = new DOMXPath( $doc );
        $query = $this->build_query_for_xpath( 'fields' );
        
        $result = $xpath->query($query);
        $src = $result->item($move_from + $offset);
        $tag = $result->item($move_to + $offset);
        if( $move_from == $move_to ) return;
        if($move_from > $move_to){  
            // Move up
            $tag->parentNode->insertBefore($src, $tag);
        }else{ 
            // Move down
            $tag->parentNode->insertBefore($src, $result->item($move_to + $offset + 1));
        }
        $doc->save( PATH_XML . $table_name . "_snippet.xml"); 
    }


    /* ------------------------------------------------------------ *\
    | - FUNC Purpose	: Add new node (current: add new node for detailview node) 
    | - Parameters		: 
    |		Name			Type		Description
    |		---------------------------------------------------
    |		$table_name     string      file name XML (filename XML = $table-name + '_snippet.xml')							
    |	    $data           string      value of node: field_id, label
    | - Return
    |			- N/A
    \* ------------------------------------------------------------ */
    function add_child_node( $table_name, $data, $insert_to_node ){
        $doc = new DOMDocument('1.0', 'iso-8859-1'); 
        $doc->formatOutput = true; 
        $doc->preserveWhiteSpace = false;
        $doc->load( PATH_XML . $table_name . "_snippet.xml");    
        
        $xpath = new DOMXPath($doc);
        $query = "//ja/" . $insert_to_node;
        
        $result = $xpath->query($query);
        // Field
        $field = $doc->createElement('field');
        $result->item(0)->appendChild($field);
        
            // Field id
            $field_id = $doc->createElement('field_id', $data);
            $field->appendChild($field_id);
            // Field label
            $label = $doc->createElement('label', $data);
            $field->appendChild($label);
                 
        $doc->save( PATH_XML . $table_name . "_snippet.xml");
    }
    
    /* ------------------------------------------------------------ *\
    | - FUNC Purpose	: 
    | - Parameters		: 
    |		Name			Type		Description
    |		---------------------------------------------------
    |		N/A							
    |								
    | - Return
    |			- N/A 
    \* ------------------------------------------------------------ */
    function build_query_for_xpath( $node ){
        switch( $node ){
            case 'actions':
                return "//ja/masterview/" . $node . "/*";
            case 'customactions':
                return "//ja/" . $node . "/*";  
            case 'masterview':
                return "//ja/" . $node . "/fields/*";
            case 'detailview':
                return "//ja/" . $node . "/*";
            case 'fields':
                return "//ja/" . $node . "/*";
            default:
                return "//ja/*";     
        }
    }
    
    
    /* ------------------------------------------------------------ *\
    | - FUNC Purpose	: Get header data from XML
    | - Parameters		: 
    |		Name             Type		 Description
    |		---------------------------------------------------
    |		$table_name      string      see [add_child_node] function
    |	    $node            string      node to selected in '//ja/header' 
    | - Return 
    |			- string: value in $node 
    \* ------------------------------------------------------------ */
    function get_header_infor($table_name, $node){
        $doc = new DOMDocument('1.0', 'iso-8859-1'); 
        $doc->load( PATH_XML . $table_name . "_snippet.xml");        
        
        $xpath = new DOMXPath($doc);
        $query = "//ja/header/" . $node;
        $result = $xpath->query($query);

        return $result->item(0)->nodeValue;
    }

    /* ------------------------------------------------------------ *\
    | - FUNC Purpose	: Get action in masterview node
    | - Parameters		: 
    |		Name			Type		Description
    |		---------------------------------------------------
    |		$table_name     string      file name XML (filename XML = $table-name + '_snippet.xml')													
    |	    $node           string      node to get value
    | - Return
    |			- array: value at $node
    \* ------------------------------------------------------------ */
    function get_actions( $table_name, $node ){
        $doc = new DOMDocument('1.0', 'iso-8859-1');
        $doc->load( PATH_XML . $table_name . "_snippet.xml");
        
        // load xpath
        $xpath = new DOMXPath( $doc );
        $query = $this->build_query_for_xpath( $node );

        $result = $xpath->query($query); 
        
        $actions = array();
        for($i = 0; $i < $result->length ; $i++){
            $actions[$xpath->query( $query. "/id")->item($i)->nodeValue] = array(
                'id'    => $xpath->query( $query. "/id")->item($i)->nodeValue,
                'label' => $xpath->query( $query. "/label")->item($i)->nodeValue,
                'url'   => $xpath->query( $query. "/url")->item($i)->nodeValue
            );  
        }
        return $actions;
    }

    /* ------------------------------------------------------------ *\
    | - FUNC Purpose	: Get data at node customactions
    | - Parameters		: 
    |		Name			Type		Description
    |		---------------------------------------------------
    |		$table_name     string      file name XML (filename XML = $table-name + '_snippet.xml')													
    |	    $node           string      node to get value						
    |								
    | - Return
    |			- array: value at $node
    \* ------------------------------------------------------------ */
    function get_customactions( $table_name, $node){
        $doc = new DOMDocument('1.0', 'iso-8859-1');
        $doc->load( PATH_XML . $table_name . "_snippet.xml");
        
        // load xpath
        $xpath = new DOMXPath( $doc );
        $query = $this->build_query_for_xpath( $node );
        $result = $xpath->query($query);
        
        $custom_actions = array( );
        for($i = 0; $i < $result->length ; $i++){
            $custom_actions[] = array(
                'action_name'    => $xpath->query( $query. "/action_name")->item($i)->nodeValue,
                'action_func' => $xpath->query( $query. "/action_func")->item($i)->nodeValue,
            );  
        }
        return $custom_actions;
    }
    
    /* ------------------------------------------------------------ *\
    | - FUNC Purpose	: Get data at node masterview
    | - Parameters		: 
    |		Name			Type		Description
    |		---------------------------------------------------
    |		$table_name     string      file name XML (filename XML = $table-name + '_snippet.xml')													
    |	    $node           string      node to get value							
    |								
    | - Return
    |			- array: value at $node 
    \* ------------------------------------------------------------ */
    function get_masterview( $table_name, $node ){
        $doc = new DOMDocument('1.0', 'iso-8859-1');
        $doc->load( PATH_XML . $table_name . "_snippet.xml");
        
        // load xpath
        $xpath = new DOMXPath( $doc );
        $query = $this->build_query_for_xpath( $node );
        $result = $xpath->query($query); 
        
        $masterview = array();
        $control = array(); // Contain control info. Ex: type, id, value, selected
        for($i = 0; $i < $result->length; $i++){
            $id = $xpath->query($query . "/field_id")->item($i)->nodeValue;
            $masterview[$id] = array(
                'field_id' => $xpath->query($query . "/field_id")->item($i)->nodeValue,
                'label' => $xpath->query($query . "/label")->item($i)->nodeValue,
                'control' => array()
                );
                
            $ctrl_type = $xpath->query($query . "/control/control_type")->item($i)->nodeValue;
            // Check field exist control display
            // -------------------------------------------  
            if( !empty( $ctrl_type ) ){
                $control['control_type']    = $ctrl_type;
                $control['control_value']   = array(
                        'default' => $xpath->query($query . "/control/control_value/default")->item(0)->nodeValue,
                        'id' => $xpath->query($query . "/control/control_value/id")->item(0)->nodeValue,
                        'value' => $xpath->query($query . "/control/control_value/value")->item(0)->nodeValue,
                        );  
                $masterview[$id]['control'] = $control;  
            }
        }
        return $masterview;
    }
    
    
    /* ------------------------------------------------------------ *\
    | - FUNC Purpose	: Get data at node detailview
    | - Parameters		: 
    |		Name			Type		Description
    |		---------------------------------------------------
    |		$table_name     string      file name XML (filename XML = $table-name + '_snippet.xml')													
    |	    $node           string      node to get value						
    |								
    | - Return
    |			- array: value at $node
    \* ------------------------------------------------------------ */
    function get_detailview( $table_name, $node ){
        $doc = new DOMDocument('1.0', 'iso-8859-1');
        $doc->load( PATH_XML . $table_name . "_snippet.xml");
        
        // load xpath
        $xpath = new DOMXPath( $doc );
        $query = $this->build_query_for_xpath( $node );
        $fields = $xpath->query($query); 
            
        $detailview = array();
        for($i = 0; $i < $fields->length ; $i++){ // Loop fields in detail    
            $control = array(); // Contain control info. Ex: type, id, value, selected
            $id = $xpath->query( $query. "/field_id")->item($i)->nodeValue;
            
            $detailview[$id] = array(
                'field_id'    => $xpath->query( $query. "/field_id")->item($i)->nodeValue,
                //'label' => $xpath->query( $query. "/label")->item($i)->nodeValue,
                'control' => array()
            );
                
            if($xpath->query($query . "[field_id='".$detailview[$id]['field_id']."']/control/control_type")->length > 0){ // Exist control
                
                $ctrl_type = $xpath->query($query . "[field_id='".$detailview[$id]['field_id']."']/control/control_type")->item(0)->nodeValue;
                if( !empty($ctrl_type) ){
                    $number_control = $xpath->query($query . "[field_id='".$detailview[$id]['field_id']."']/control/control_value")->length;
                    
                    $control['control_type']    = $ctrl_type;
                    for( $j = 0; $j < $number_control; $j++ ){
                        
                        $control['control_value'][]   = array(
                                'default' => $xpath->query($query . "[field_id='".$detailview[$id]['field_id']."']/control/control_value/default")->item($j)->nodeValue,
                                'id' => $xpath->query($query . "[field_id='".$detailview[$id]['field_id']."']/control/control_value/id")->item($j)->nodeValue,
                                'value' => $xpath->query($query . "[field_id='".$detailview[$id]['field_id']."']/control/control_value/value")->item($j)->nodeValue,
                                );
                       
                        $detailview[$id]['control'] = $control;
                    }        
                }
            }
        }
        return $detailview;        
             
    }
    
    /* ------------------------------------------------------------ *\
    | - FUNC Purpose	: Get fields from table
    | - Parameters		: 
    |		Name			Type		Description
    |		---------------------------------------------------
    |		$table_name     string      file name XML (filename XML = $table-name + '_snippet.xml')													
    |	    $node           string      node to get value							
    |								
    | - Return
    |			- array: value at $node
    \* ------------------------------------------------------------ */
    function get_fields( $table_name, $node ){
        $doc = new DOMDocument('1.0', 'iso-8859-1');
        $doc->load( PATH_XML . $table_name . "_snippet.xml");
        
        // load xpath
        $xpath = new DOMXPath( $doc );
        $query = $this->build_query_for_xpath( $node );
        $result = $xpath->query($query); 

        $rules = array(); 
        for( $i = 0; $i < $result->length; $i++){
            $id = $xpath->query( $query. "/field_id")->item($i)->nodeValue;
            $rules[ $id ] = array(
                'field_id'  => $xpath->query( $query. "/field_id")->item($i)->nodeValue,
                'label'  => $xpath->query( $query. "/label")->item($i)->nodeValue,
                'rules'     => $xpath->query( $query. "/rules")->item($i)->nodeValue,
            );
        }   
        return $rules;
    }
    
    function exist_control( $table_name, $field_id){
        $doc = new DOMDocument('1.0', 'iso-8859-1');
        $doc->load( PATH_XML . $table_name . "_snippet.xml");
        
        // load xpath
        $xpath = new DOMXPath( $doc );
        $query = "//ja/detailview/*";
        $field_array = $xpath->query( $query );
        
        $control_data = array();
        
        if( $field_array->length > 0 ){  // Exist fields in detail
            $query = $query . "[field_id='" . $field_id . "']/control";
            
            // $control->length = 0 (default: text entry) 
            if($xpath->query($query)->length > 0){
                return TRUE;
            }else{
                return FALSE;
            }
        }else{
            return FALSE;
        }
    }
    
    function get_control_of_field( $table_name, $field_id ){
        $doc = new DOMDocument('1.0', 'iso-8859-1');
        $doc->load( PATH_XML . $table_name . "_snippet.xml");
        
        // load xpath
        $xpath = new DOMXPath( $doc );
        $query = "//ja/detailview/*";
        $field_array = $xpath->query( $query );
        
        $control_data = array();
        
        if( $field_array->length > 0 ){  // Exist fields in detail
            $query = $query . "[field_id='" . $field_id . "']/control";
            $control = $xpath->query($query);
            
            // $control->length = 0 (default: text entry) 
            if($control->length > 0){
                $control_type = $xpath->query($query . "/control_type")->item(0)->nodeValue;
                $control_value = $xpath->query($query . "/control_value");
                $control_data['field_name'] = $field_id;
                $control_data[$control_type] = array();
                for( $i = 0; $i < $control_value->length; $i++){
                    $control_data[$control_type][] = array(
                        'default' => trim($xpath->query($query . "/control_value/default")->item($i)->nodeValue),
                        'id'      => trim($xpath->query($query . "/control_value/id")->item($i)->nodeValue),
                        'value'   => trim($xpath->query($query . "/control_value/value")->item($i)->nodeValue),
                    );
                }
            }
        }else{
            return NULL; // No fields in detail
        }
        
        print_r($control_data);
        die;
        
        // $control_data = array empty: text entry
        return $control_data;
    }
    
    function get_label_of_control( $table, $field_id ){
       
    }
    
    
    // Make array data from a node
    function get_node($table_name, $node){
        $doc = new DOMDocument('1.0', 'iso-8859-1');
        $doc->load('application\models\xml\\'. $table_name . "_snippet.xml");

        $xpath = new DOMXPath($doc);
        $xpath2 = new DOMXPath($doc);
        $query = "//data/". $node . "/item";

        $result = $xpath->query($query);
        $retdata = array();
        $retdata2 = array();
        foreach($result as $item){
            if($node == 'rules'){
                $rules = array();
                $ret = $xpath->query("//data/". $node . "/item[@id='".$item->getAttribute('id'). "']/value");
                foreach($ret as $r){
                    $rules[] = trim($r->nodeValue);
                }
                $retdata[$item->getAttribute('id')] = $rules;
            }else{
                
                $ret2 = $xpath->query("//data/". $node . "/item[@id='".$item->getAttribute('id'). "']/control");
                //print_r("//data/". $node . "/item[@id='".$item->getAttribute('id'). "']/control");
                foreach($ret2 as $o){
                    $retdata2[$item->getAttribute('id')][$o->getAttribute('name')][] = 
                            array( array(  'id'    =>  $o->getAttribute('id'),
                                   'value' =>  $o->nodeValue));
                   
                }
                
                //if(empty($item->firstChild->nodeValue)){
                //    $retdata[$item->getAttribute('id')] = trim($item->firstChild->nodeValue);
                //}else{
                    $retdata[$item->getAttribute('id')] = trim($item->nodeValue);
                //}
            }
        }
        //print_r(array_merge($retdata,$retdata2));
        return  array_merge($retdata,$retdata2);
        //return  $retdata;    
    }
    /* ------------------------------------------------------------ *\
    | - FUNC Purpose	: Save Radio, CheckBox, ComboBox, ListBox to node (Detail view)
    | - Parameters		: 
    |		Name			Type		Description
    |		---------------------------------------------------
    |		N/A							
    |								
    | - Return
    |			- N/A 
    \* ------------------------------------------------------------ */
    function save_control( $table, $id, $value, $control_type, $parent_field, $selected = null, $flags = false ){
        $doc = new DOMDocument( '1.0', 'iso-8859-1' );
        $doc->formatOutput = true;
        $doc->preserveWhiteSpace = false;
        $doc->load( PATH_XML . $table . "_snippet.xml" );
        $xpath = new DOMXPath( $doc );
        
        // FIRST: insert control type
        if( $flags ){
            $query =  "//ja/detailview/field[field_id='". $parent_field . "']";
            $field =  $xpath->query( $query );
            $control = $doc->createElement( 'control' );
            $field->item(0)->appendChild( $control );
                // Control type
                $control->appendChild( $doc->createElement( 'control_type', $control_type ) );
        }else{
        // LAST: insert list control value
            $query =  "//ja/detailview/field[field_id='". $parent_field . "']/control";
            $control =  $xpath->query( $query );
            // Control value
            $control_value = $doc->createElement( 'control_value' );
            $control->item(0)->appendChild( $control_value );
                // Selected
                if( isset( $selected ) ){
                    $control_value->appendChild( $doc->createElement( 'default', 'true' ) );
                }else{
                    $control_value->appendChild( $doc->createElement( 'default', 'false' ) );
                }
                // id
                $control_value->appendChild( $doc->createElement( 'id', $id ) );
                // value
                $control_value->appendChild( $doc->createElement( 'value', $value ) );
        }
        
        $doc->save("application\models\xml\\" . $table . "_snippet.xml");
    }
    
    // Save all data to xml file
    function save_to_xml( $data ){
        $add_delete_del     =   $data[ 'actions' ] ;
        $cus_act            =   $data[ 'custom_actions' ];
        $master             =   $data[ 'master_view' ];
        $detail             =   $data[ 'detail_view' ];
        $labels_of_fields   =   $data[ 'labels' ];
        $display_types      =   $data[ 'display_types' ];
        $records            =   $data[ 'records' ];
        $rules_data         =   $data[ 'rules' ];
        $controller         =   $data[ 'controller']; 
        $view               =   $data[ 'view'];
        $validation         =   $data[ 'validation'];
        $table_name         =   $data['table'];
        $primarykey         =   $data['primarykey'];
        
        // Remove file if exist
        if(file_exists( PATH_XML . $table_name . "_snippet.xml")){
            unlink( PATH_XML . $table_name . "_snippet.xml");
        }
        
        $doc = new DOMDocument('1.0', 'iso-8859-1'); 
        $doc->formatOutput = true;
        // ROOT
        $ja = $doc->createElement('ja');
        $doc->appendChild($ja);

        //$data->appendChild($description);

// BEGIN: Header
        // Header
        $header = $doc->createElement('header');
        $ja->appendChild($header);  
                 
            // Creation date
            $creation_date = $doc->createElement('creation_dt', date("m/d/Y H:i"));
            $header->appendChild($creation_date);
            
            // Table
            $table = $doc->createElement('table', $table_name);
            $header->appendChild($table);
            
            // Description
            $description = $doc->createElement('description', 'Description here...' );
            $header->appendChild($description);
                
            // Name
            $name_controller = $doc->createElement('name_controller', $controller);
            $header->appendChild($name_controller);
            
            // View
            $name_view = $doc->createElement('name_view', $view);
            $header->appendChild($name_view);
            
            // Validation
            $name_validation_rule = $doc->createElement('name_validation_rule', $validation);
            $header->appendChild($name_validation_rule);
// END: Header

            // Primary key (REMOVE LATE)
            $primarykey = $doc->createElement('primarykey', $primarykey);
            $header->appendChild($primarykey);
            
// -------------------------

// BEGIN: Master view
        $master_view = $doc->createElement('masterview');
        $ja->appendChild($master_view); 
            
            // View type
            $view_type = $doc->createElement('view_type');
            $master_view->appendChild($view_type);
            
                // Type
                $type = $doc->createElement('type', 'normal');
                $view_type->appendChild($type);
            
            // Actions
            $actions = $doc->createElement('actions');
            $master_view->appendChild($actions);
                foreach($add_delete_del as $id => $label){
                    $action = $doc->createElement('action');
                    $actions->appendChild($action);
                        $action->appendChild($doc->createElement('id', $id));
                        $action->appendChild($doc->createElement('label', ucfirst($label)));
                        if(strtolower($id) == 'new'){
                            $action->appendChild($doc->createElement('url', 'index.php/'. $table_name .'/add/'));
                        }else if(strtolower($id) == 'edit'){
                            $action->appendChild($doc->createElement('url', 'index.php/'. $table_name .'/edit/'));
                        }else{
                            $action->appendChild($doc->createElement('url', ''));
                        }
                }
            // Fields
            $master_fields = $doc->createElement('fields');
            $master_view->appendChild($master_fields);
                foreach($master as $field_id => $label){
                    $master_field = $doc->createElement('field');
                    $master_fields->appendChild($master_field);
                        $master_field->appendChild($doc->createElement('field_id', $field_id));
                        $master_field->appendChild($doc->createElement('label', $label));      
                            
                    // Control
                    $control = $doc->createElement('control');
                    $master_field->appendChild($control);
                        // Control type
                        $control->appendChild($doc->createElement('control_type',''));
                            // Control value
                            $control_value = $doc->createElement('control_value');
                            $control->appendChild($control_value);
                                $control_value->appendChild($doc->createElement('default', ''));
                                $control_value->appendChild($doc->createElement('id', ''));
                                $control_value->appendChild($doc->createElement('value', ''));
                }
// END: Master view

// -------------------------

// BEGIN: Detail view
            $detail_view = $doc->createElement('detailview');
            $ja->appendChild($detail_view);
// END: Detail view
  
// -------------------------

// BEGIN: Custom action
            $custom_actions = $doc->createElement( 'customactions' );
            $ja->appendChild( $custom_actions );

            if( strlen( $cus_act ) ){            
                $temp = explode( '|', $cus_act );
                foreach( $temp as $act ){
                    // Create action
                    $actions = $doc->createElement( 'actions' );
                    $custom_actions->appendChild( $actions );
                    $temp2 = explode( '=', $act );  // temp2[0]: action; temp[1]: func
                        // Action name
                        $actions->appendChild( $doc->createElement( 'action_name', ucfirst( $temp2[ 0 ] ) ) );
                        // Action func 
                        $actions->appendChild( $doc->createElement( 'action_func', $temp2[ 1 ] ) );
                }
            }
                  
// END: Custom action

// -------------------------

// BEGIN: Fields
            $rules = $doc->createElement('fields');
            $ja->appendChild($rules);
                foreach($rules_data as $field_id => $value){
                    $rule = $doc->createElement('field');
                    $rules->appendChild($rule);
                        $rule->appendChild($doc->createElement('field_id', $field_id));
                        $rule->appendChild($doc->createElement('label', $labels_of_fields[$field_id]));
                        $rule->appendChild($doc->createElement('rules', implode('|', $value)));
                }
// END: Fields
        $doc->save( PATH_XML . $table_name . "_snippet.xml");
    }
    
    // Add new data
    function add_element($doc, $root, $parent_node, $data = array()){
        foreach($data as $id => $name){
            $attr = $doc->createAttribute('id');
            $attr->appendChild($doc->createTextNode($id));

            $item = $doc->createElement('item');
            $item->appendChild($attr);
            
            $subitem = $doc->createElement('value', $name);
            $item->appendChild($subitem);
            
            $parent_node->appendChild($item);
            $root->appendChild($parent_node);
        }
    }
}
?>